package action

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha1"
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/session"
	"io"
	"teamcoop/global"
	. "teamcoop/models"
	"time"
)

func mysha1(c string) (ret string) {

	h := sha1.New()
	io.WriteString(h, c)
	ret = fmt.Sprintf("%x", h.Sum(nil))
	return
}

// generate session id with rand string, unix nano time, user email by hash function.
func generateMySID(email string) (sid string) {
	bs := make([]byte, 24)
	if _, err := io.ReadFull(rand.Reader, bs); err != nil {
		bs = []byte("还是嫉妒恨你特么联系哦是")
	}
	sig := fmt.Sprintf("%s%d%s", email, time.Now().UnixNano(), bs)
	h := hmac.New(sha1.New, []byte(""))
	fmt.Fprintf(h, "%s", sig)
	sid = hex.EncodeToString(h.Sum(nil))
	return
}

func UserRegister(email string, nick string, pwd string, class int8) (uid int64, err error) {
	uid = -1

	user := &User{
		Email: email,
		Nick:  nick,
		Pwd:   mysha1(pwd),
		Class: class,
	}

	o := orm.NewOrm()
	qs := o.QueryTable("user")
	_, err = qs.Filter("email", email).Count()
	//email如果重复，返回错误
	if err != nil {
		err = errors.New("the email has registed!")
		return
	}

	uid, err = o.Insert(user)
	//有错，返回nil
	if err != nil {
		err = errors.New("add user fail!")
		return
	}
	return
}
func UserLogin(email string, pwd string) (sid string, err error) {
	sid = ""

	o := orm.NewOrm()
	user := &User{}
	err = o.QueryTable("user").Filter("email", email).One(user)
	if err != nil {
		err = errors.New("email or password error!")
		return
	}
	if user.Pwd != mysha1(pwd) {
		err = errors.New("email or password error!")
		return
	}
	sid = generateMySID(email)
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		err = errors.New("internal error!")
		return
	}
	sessions.Set(string("login_state"), string("logined"))
	sessions.Set(string("login_email"), string(email))
	sessions.Set(string("sid"), string(sid))
	return
}
func UserInfo(sid string) (email string, nick string, class int8, err error) {
	email = ""
	nick = ""
	class = -1
	//获取session
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}

	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	email = sessions.Get("login_email").(string)
	//通过email查询获取用户信息
	o := orm.NewOrm()
	user := &User{}
	qs := o.QueryTable("user")
	err = qs.Filter("email", email).One(user)
	if err != nil {
		err = errors.New("user is exsit!")
		return
	}
	email = user.Email
	nick = user.Nick
	class = user.Class
	return
}

func UserInfoOther(sid string, uid int64) (email string, nick string, class int8, err error) {
	email = ""
	nick = ""
	class = -1
	//获取session
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}

	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	//通过email查询获取用户信息
	o := orm.NewOrm()
	user := &User{}
	qs := o.QueryTable("user")
	err = qs.Filter("Id", uid).One(user)
	if err != nil {
		err = errors.New("user is not exsit!")
		return
	}
	email = user.Email
	nick = user.Nick
	class = user.Class
	return
}

func UserRemove(sid string, uid int64) (err error) {
	//获取session
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}

	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	//通过email查询获取用户信息
	o := orm.NewOrm()
	setter_user := &User{}
	email := sessions.Get("login_email").(string)

	qs := o.QueryTable("user")
	err = qs.Filter("email", email).One(setter_user)
	if err != nil {
		err = errors.New("login user is not exsit!")
		return
	}
	if setter_user.Class < 2 {
		err = errors.New("permission denein!")
		return
	}

	target_user := &User{}
	qs = o.QueryTable("user")
	err = qs.Filter("Id", uid).One(target_user)
	if err != nil {
		err = errors.New("user is not exsit!")
		return
	}
	if setter_user.Id == target_user.Id {
		err = errors.New("can't delete yourself user record!")
		return
	}

	o.Delete(target_user)
	return
}
func UserSetNick(sid string, target_id int64, nick string) (err error) {
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}
	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	seter_email := sessions.Get("login_email").(string)

	//通过email查询获取用户信息
	o := orm.NewOrm()
	setter_user := &User{}
	target_user := &User{}
	qs := o.QueryTable("user")
	err = qs.Filter("email", seter_email).One(setter_user)
	if err != nil {
		err = errors.New("user is exsit!")
		return
	}

	qs = o.QueryTable("user")
	err = qs.Filter("id", target_id).One(target_user)
	if err != nil {
		err = errors.New("target user is not exsit!")
		return
	}
	if setter_user.Id != target_id || setter_user.Class < 1 {
		err = errors.New("permission denein!")
		return
	}

	target_user.Nick = nick
	_, err = o.Update(target_user, "nick")
	if err != nil {
		err = errors.New("set user's nick fail!")
		return
	}
	return
}
func UserSetClass(sid string, target_id int64, class int8) (err error) {
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}
	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	seter_email := sessions.Get("login_email").(string)

	//通过email查询获取用户信息
	o := orm.NewOrm()
	user := &User{}
	qs := o.QueryTable("user")
	err = qs.Filter("email", seter_email).One(user)
	if err != nil {
		err = errors.New("user is exsit!")
		return
	}
	if user.Class <= 1 {
		err = errors.New("permission denein!")
		return
	}

	qs = o.QueryTable("user")
	err = qs.Filter("id", target_id).One(user)
	if err != nil {
		err = errors.New("target user is not exsit!")
		return
	}
	user.Class = class
	_, err = o.Update(user, "class")
	if err != nil {
		err = errors.New("set user's class fail!")
		return
	}
	return
}

func UserUpdate(sid string, nick string, pwd string, class int8) (err error) {
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}
	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	email := sessions.Get("login_email").(string)

	//通过email查询获取用户信息
	o := orm.NewOrm()
	user := &User{}
	qs := o.QueryTable("user")
	err = qs.Filter("email", email).One(user)
	if err != nil {
		err = errors.New("user is exsit!")
		return
	}

	if nick != "" {
		user.Nick = nick
	}

	if pwd != "" {
		user.Pwd = mysha1(pwd)
	}

	if class >= 0 {
		user.Class = class
	}
	return
}

func UserLogout(sid string) (err error) {
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}

	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	sessions.Set("login_state", "logouted")
	err = sessions.Flush()
	if err != nil {
		err = errors.New("internal error!")
		return
	}
	return
}

func UserList(sid string) (ret_list []User, err error) {
	var sessions session.SessionStore
	sessions, err = global.MySessions.GetSessionStore(sid)
	if err != nil {
		return
	}
	//从session里获取当前登录的用户email
	state := sessions.Get("login_state")
	if "logined" != state {
		err = errors.New("user is not login!")
		return
	}
	o := orm.NewOrm()
	qs := o.QueryTable("user")
	_, err = qs.All(&ret_list)
	return
}
